package agents;

import interfaces.CarStatus;
import interfaces.Settings;
import message.CPMessage;
import model.agent.Agent;

public class CarParkAgent extends Agent {
	
	private static final String WaitToEnterList = "WaitToEnterList";
	private static final String ParkingList = "ParkingList";
	private static final String WaitToLeaveList = "WaitToLeaveList";
	private static final String ParkingSpace = "ParkingSpace";
	private static final String WaitToChargeList = "WaitToChargeList";
	private static final String ChargingList = "ChargingList";
	private static final String ChargingCapacity = "ChargingCapacity";

	/**
	 * Constructor
	 */
	public CarParkAgent(String id) {
		super(id);
		initText(TYPE, "CarPark");
		initInt(ParkingSpace, Settings.PARKING_SPACE);
		
		// STATUS
		initDependency(WaitToEnterList);
		initDependency(ParkingList);
		initDependency(WaitToLeaveList);
		
		// STAGE
		initDependency(WaitToChargeList);
		initDependency(ChargingList);
		
		// SETTING
		initInt(ChargingCapacity, Settings.CHARGING_CAPACITY);
		
	}
	
	@Override
	public void act() {
		// REQUEST TO PARK or LEAVE
		while (messages().hasMessage()) {
			CPMessage receiveMessage = (CPMessage)messages().getMessage();
			if (receiveMessage.getStatus() == CarStatus.REQUEST_TO_PARK) {
				carWantsToEnter(receiveMessage.getFromID());
			} else if (receiveMessage.getStatus() == CarStatus.REQUEST_TO_LEAVE) {
				carWantsToLeave(receiveMessage.getFromID());
			} else if (receiveMessage.getIsFullyCharged() == true) {
				isFullyCharged(receiveMessage.getFromID());
			}
		}
		
		// PARK
		while (!(getDependencyIDs(WaitToEnterList).isEmpty()) && ((getDependencyIDs(ParkingList).size() < getInt(ParkingSpace)))) {
			carEnter(getDependencyIDs(WaitToEnterList).get(0));
		}
		
		// CHARGE
		while (!(getDependencyIDs(WaitToChargeList).isEmpty()) && ((getDependencyIDs(ChargingList).size() < getInt(ChargingCapacity)))) {
			carCharged(getDependencyIDs(WaitToChargeList).get(0));
		}
		
		charingCar();
		
		// LEAVE
		while (!(getDependencyIDs(WaitToLeaveList).isEmpty())) {
			carLeave(getDependencyIDs(WaitToLeaveList).get(0));
		}
	}
	
	public void carWantsToEnter(String id) {
		addDependencyID(WaitToEnterList, id);
	}
	
	public void carEnter(String id) {
		CPMessage deliverMessage = new CPMessage(getID(), CarStatus.ENTER);
		messages().sendMessage(getDependencyIDs(WaitToEnterList).get(0), deliverMessage);
		addDependencyID(ParkingList, id);
		removeDependencyID(WaitToEnterList, id);
		carWantsToCharge(id);
	}
	
	public void carWantsToCharge(String id) {
		addDependencyID(WaitToChargeList, id);
	}
	
	public void carCharged(String id) {
		addDependencyID(ChargingList, id);
		removeDependencyID(WaitToChargeList, id);
	}
	
	public void carWantsToLeave(String id) {
		addDependencyID(WaitToLeaveList, id);
	}
	
	public void carLeave(String id) {
		CPMessage deliverMessage = new CPMessage(getID(), CarStatus.LEAVE);
		messages().sendMessage(getDependencyIDs(WaitToLeaveList).get(0), deliverMessage);
		removeDependencyID(ParkingList, id);
		removeDependencyID(WaitToLeaveList, id);
		removeDependencyID(ChargingList, id);
	}
	
	// METHOD
	public void charingCar() {
		for (int i = 0; i < getDependencyIDs(ChargingList).size(); i++) {
			CPMessage deliverMessage = new CPMessage(getID(), "");
			messages().sendMessage(getDependencyIDs(ChargingList).get(i), deliverMessage);
		}
	}
	
	public void isFullyCharged(String id) {
		removeDependencyID(ChargingList, id);
	}
	
}
